package com.ai.smlcore.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class FtpUtil {

    protected static transient Log logger = LogFactory.getLog(FtpUtil.class);

    public static final String FILE_SPEARATROR = "/";
    public static final int BIN = 0;
    public static final int ASC = 1;

    protected static FTPClient client = new FTPClient();
    private String localPath = null;

    private String _host = null;
    private int _port = 0;

    private String _username = null;
    private String _password = null;
    private String _remotePath = null;
    // private String _localPath = null;
    // private String _localPathTemp = null;
    private String remotePathHis;// FTP文件历史目录,在cfg_ftp_path表remote_path_his字段配置
    private FTPClient ftpClient = new FTPClient();
    private static String encoding = System.getProperty("file.encoding");

    /**
     * @param ftpPathCode
     *            String
     * @throws Exception
     */
    public FtpUtil(String ftpPathCode) throws Exception {

    }

    /**
     * @param hostIp
     * @param port
     * @param username
     * @param password
     * @param remotepath
     * @param localPath2
     * @param remotePathHis2
     * @param localPathTemp
     */
    public FtpUtil(String hostIp, int port, String username, String password, String remotepath, String remotePathHis,
        String encoding) throws Exception {
        logger.debug("hostIp --> " + hostIp + " , port -->" + port + " , username -->" + username + " , password -->"
                + password + " , remotepath -->" + remotepath + " , remotePathHis -->" + remotePathHis);
        client = new FTPClient();
        client.connect(hostIp, port);
        client.login(username, password);
        client.changeWorkingDirectory(remotepath);
        _host = hostIp;
        _port = port;
        _username = username;
        _password = password;
        _remotePath = remotepath;
        FtpUtil.encoding = encoding;
        // _localPath = localPath;
        // _localPathTemp = remotePathHis;
    }

    /**
     * @param hostIp
     * @param port
     * @param username
     * @param password
     * @param remotepath
     * @param localPath2
     * @param remotePathHis2
     * @param localPathTemp
     */
    public FtpUtil(String hostIp, int port, String username, String password, String remotepath, String remotePathHis)
            throws Exception {
        logger.debug("hostIp --> " + hostIp + " , port -->" + port + " , username -->" + username + " , password -->"
                + password + " , remotepath -->" + remotepath + " , remotePathHis -->" + remotePathHis);
        client = new FTPClient();
        client.connect(hostIp, port);
        client.login(username, password);
        client.changeWorkingDirectory(remotepath);
        _host = hostIp;
        _port = port;
        _username = username;
        _password = password;
        _remotePath = remotepath;
        // _localPath = localPath;
        // _localPathTemp = remotePathHis;
    }

    /**
     * 二进制格式
     *
     * @throws Exception
     */
    public void bin() throws Exception {
        client.setFileType(FTP.BINARY_FILE_TYPE);
    }

    /**
     * ascii格式
     *
     * @throws Exception
     */
    public void asc() throws Exception {
        client.setFileType(FTP.ASCII_FILE_TYPE);
    }

    public FTPClient getFTPClient() {
        return client;
    }

    /**
     * 列出服务器的目录下面的文件
     *
     * @param encoding
     *            String
     * @return String[]
     * @throws Exception
     */
    public String[] list(String encoding) throws Exception {
        List<String> list = new ArrayList<String>();

        FTPFile[] ftpFiles = client.listFiles(client.printWorkingDirectory());

        for (FTPFile ftpFile : ftpFiles) {
            if (ftpFile.isFile()) {
                list.add(new String(ftpFile.getName().getBytes("ISO-8859-1"), encoding));
            }
        }

        return list.toArray(new String[0]);
    }

    /**
     * 根据pathName列出服务器的目录下的文件
     *
     * @param pathName
     *            文件名或文件路径
     * @return 返回FTPFile列表
     * @throws Exception
     */
    public FTPFile[] listFtpFiles(String pathName) throws Exception {
        return client.listFiles(pathName);
    }

    /**
     * @return String[]
     * @throws Exception
     */
    public String[] list() throws Exception {
        return list("GBK");
    }

    /**
     * @param remoteFileName
     *            String
     * @param input
     *            InputStream
     * @param mode
     *            int
     * @throws Exception
     */
    public void upload(String remoteFileName, InputStream input, int mode) throws Exception {
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        upload(remoteFileName, input);
    }

    /**
     * @param remoteFileName
     *            String
     * @param input
     *            InputStream
     * @throws Exception
     */
    public void upload(String remoteFileName, InputStream input) throws Exception {
        client.storeFile(remoteFileName, input);
    }

    /**
     * @param remoteFileName
     *            String
     * @param localFileName
     *            String
     * @throws Exception
     */
    public void upload(String remoteFileName, String localFileName) throws Exception {
        InputStream is = null;
        FileInputStream fileInputStream = null;
        try {
        	fileInputStream = new FileInputStream(localPath + "/" + localFileName);
            is = new BufferedInputStream(fileInputStream);
            client.storeFile(remoteFileName, is);
        } finally {
            if (is != null) {
                is.close();
            }
            if (fileInputStream != null) {
            	fileInputStream.close();
            }
        }
    }

    /**
     * @param remoteFileName
     *            String
     * @param localFileName
     *            String
     * @throws Exception
     */
    public void uploadTts(String remoteFileName, String localFileName, int mode) throws Exception {
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        InputStream is = null;
        FileInputStream fileInputStream = null;
        try {
        	fileInputStream = new FileInputStream(localFileName);
            is = new BufferedInputStream(fileInputStream);
            client.storeFile(remoteFileName, is);
        } finally {
            if (is != null) {
                is.close();
            }
            if (fileInputStream != null) {
            	fileInputStream.close();
            }
        }
    }

    /**
     * @param remoteFileName
     *            String
     * @param localFileName
     *            String
     * @param mode
     *            int
     * @throws Exception
     */
    public void upload(String remoteFileName, String localFileName, int mode) throws Exception {
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        upload(remoteFileName, localFileName);
    }

    public void uploadWithGzip(String ftpPathCode, String fileName, List<?> lines) throws Exception {
        fileName = fileName + ".gz";
        FtpUtil ftpUtil = new FtpUtil(ftpPathCode);
        OutputStream out = ftpUtil.getOutputStream(fileName);
        if (out == null) {
            throw new Exception("FTP OutputStream 为空,可能原因FTP未连接或连接超时");
        }
        GZIPOutputStream gzout = null;
        try {
            gzout = new GZIPOutputStream(out);
            IOUtils.writeLines(lines, null, gzout, "GBK");
        } catch (Exception e) {
            throw e;
        } finally {
            if (null != gzout) {
                gzout.close();
            }
            out.close();
            ftpUtil.completePendingCommand();
        }
    }

    /**
     * @param remoteFileName
     *            String
     * @param output
     *            OutputStream
     * @param mode
     *            int
     * @throws Exception
     */
    public void download(String remoteFileName, OutputStream output, int mode) throws Exception {
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        download(remoteFileName, output);
    }

    /**
     * 复杂下载,兼容复杂路径
     *
     * @param remoteFileName
     *            String
     * @param output
     *            OutputStream
     * @throws Exception
     */
    public void complexDownload(String remoteFileName, OutputStream output) throws Exception {
        // 设置为bin模式
        client.setFileType(FTP.BINARY_FILE_TYPE);

        String filePath = null;
        String downFile = remoteFileName.trim();
        if (downFile.indexOf("\\") >= 0 || downFile.indexOf("/") >= 0) {
            if (downFile.charAt(0) != '.' && downFile.charAt(0) == '/') {
                downFile = "." + downFile;
            } else {
                downFile = "./" + downFile;
            }
            if (downFile.indexOf("\\") > downFile.indexOf("/")) {
                filePath = downFile.substring(0, downFile.lastIndexOf("\\"));
                downFile = downFile.substring(downFile.lastIndexOf("\\") + 1, downFile.length());
            } else {
                filePath = downFile.substring(0, downFile.lastIndexOf("/"));
                downFile = downFile.substring(downFile.lastIndexOf("/") + 1, downFile.length());
            }
        }
        if (null != filePath) {
            changeWorkingDirectory(filePath);
        }
        if (logger.isDebugEnabled()) {
            logger.debug(client.printWorkingDirectory());
        }

        boolean rtn = client.retrieveFile(new String(downFile.getBytes("GBK"), "iso-8859-1"), output);
        if (rtn == false) {
            throw new Exception("下载远程文件:" + remoteFileName + ",不成功");
        }
    }

    /**
     * @param remoteFileName
     *            String
     * @param output
     *            OutputStream
     * @throws Exception
     */
    public void download(String remoteFileName, OutputStream output) throws Exception {
        String filePath = null;
        String downFile = remoteFileName.trim();
        if (downFile.indexOf("\\") >= 0 || downFile.indexOf("/") >= 0) {
            if (downFile.indexOf("\\") > downFile.indexOf("/")) {
                filePath = downFile.substring(0, downFile.lastIndexOf("\\"));
                downFile = downFile.substring(downFile.lastIndexOf("\\") + 1, downFile.length());
            } else {
                filePath = downFile.substring(0, downFile.lastIndexOf("/"));
                downFile = downFile.substring(downFile.lastIndexOf("/") + 1, downFile.length());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("文件路径:" + filePath + ",下载文件名:" + downFile);
            logger.debug("当前目录:" + client.printWorkingDirectory());
        }
        if (null != filePath) {
            changeWorkingDirectory(filePath);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("切换到的目录:" + client.printWorkingDirectory());
        }

        boolean rtn = client.retrieveFile(downFile, output);
        if (rtn == false) {
            throw new Exception("下载远程文件:" + remoteFileName + "不成功！");
        }
    }

    public void downloadSimple(String remoteFileName, OutputStream output) throws Exception {
        boolean rtn = client.retrieveFile(remoteFileName, output);
        if (rtn == false) {
            throw new Exception("下载远程文件:" + remoteFileName + ",不成功");
        }
    }

    /**
     *
     * @Description: 下载指定目录中所有包含某个字符的文件，包含子文件
     * @param remotePath 远程根目录下文件：根目录为“/”
     * @param localPath 下载到本地的目录
     * @param containsStr
     * @throws Exception
     * @ReturnType List<String> 返回下载到本地的文件列表
     * @author: qinzheng
     * @Created 2015年10月26日 下午2:35:08
     */
    public List<String> downAllContainFiles(String remotePath, String localPath, String containsStr) throws Exception {

        List<String> localFileList = new ArrayList<String>();

        if (remotePath.startsWith("/") && remotePath.endsWith("/")) {

            client.changeWorkingDirectory(remotePath);

            FTPFile[] files = client.listFiles(remotePath);
            for (FTPFile file : files) {
                if (file.isFile()) {
                    String fileName = new String(file.getName().getBytes(StringUtil.ENCODING.ISO_8858_1), encoding);
                    if (file.isFile() && fileName.contains(containsStr)) {
                        String localFile = localPath + "/" + fileName;
                        localFileList.add(localFile);
                        download(fileName, localFile);
                    }
                } else if (file.isDirectory()) {
                    String currDirPath = remotePath + file.getName() + "/";
                    client.changeWorkingDirectory(currDirPath);
                    localFileList.addAll(downAllContainFiles(currDirPath, localPath, containsStr));
                }
            }
            if (!"/".equals(client.printWorkingDirectory())) {
                client.changeToParentDirectory();
            }
        }
        return localFileList;
    }

    /**
     * @param remoteFileName
     *            String
     * @param localFileName
     *            String
     * @param mode
     *            int
     * @throws Exception
     */
    public void download(String remoteFileName, String localFileName, int mode) throws Exception {
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        download(remoteFileName, localFileName);
    }

    /**
     * @param remoteFileName
     *            String
     * @param localFileName
     *            String
     * @throws Exception
     */
    public void download(String remoteFileName, String localFileName) throws Exception {
        OutputStream os = null;
        FileOutputStream outputStream = null;
        String filePath = "";
        try {
            if (null != localPath && !localPath.equals("")) {
                filePath = localPath + "/" + localFileName;
            } else {
                filePath = localFileName;
            }
            outputStream = new FileOutputStream(filePath);
            os = new BufferedOutputStream(outputStream);
            if (client.isConnected() && client.isAvailable()) {
                boolean rtn = client.retrieveFile(remoteFileName, os);
                if (rtn == false) {
                    throw new Exception("下载远程文件:" + client.printWorkingDirectory() + remoteFileName + ",不成功");
                }
            } else {
                throw new Exception("远程连接断开，下载远程文件:" + remoteFileName + ",不成功");
            }
        } finally {
            if (os != null) {
                os.close();
            }
            if (outputStream != null) {
            	outputStream.close();
			}
        }
    }

    /**
     * @param remoteFileName
     *            String
     * @param localFileName
     *            String
     * @throws Exception
     */
    public void downloadTts(String remoteFileName, String localFileName, int mode) throws Exception {
        OutputStream os = null;
        FileOutputStream outputStream = null;
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        try {
        	outputStream = new FileOutputStream(localFileName);
            os = new BufferedOutputStream(outputStream);
            boolean rtn = client.retrieveFile(remoteFileName, os);
            if (rtn == false) {
                throw new Exception("下载远程文件:" + remoteFileName + ",不成功");
            }
        } finally {
            if (os != null) {
                os.close();
            }
            if (outputStream != null) {
            	outputStream.close();
			}
        }
    }

    /**
     * @param remoteFileName
     *            String
     * @return InputStream
     * @throws Exception
     */
    public InputStream readRemote(String remoteFileName) throws Exception {
        return client.retrieveFileStream(remoteFileName);
    }

    /**
     * @param remoteFileName
     *            String
     * @param mode
     *            int
     * @return InputStream
     * @throws Exception
     */
    public InputStream readRemote(String remoteFileName, int mode) throws Exception {
        if (mode == BIN) {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        } else if (mode == ASC) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            throw new Exception("不支持的传输模式:" + mode);
        }
        return readRemote(remoteFileName);
    }

    /**
     * @param oldRemoteFileName
     *            String
     * @param newRemoteFileName
     *            String
     * @throws Exception
     */
    public void rename(String oldRemoteFileName, String newRemoteFileName) throws Exception {
        client.rename(oldRemoteFileName, newRemoteFileName);
    }

    /**
     * @param remoteFileName
     *            String
     * @throws Exception
     */
    public static void delete(String remoteFileName) throws Exception {
        boolean rtn = client.deleteFile(remoteFileName);
        if (rtn == false) {
            throw new Exception("删除远程文件:" + remoteFileName + ",不成功");
        }
    }

    /**
     * @throws Exception
     */
    public void completePendingCommand() throws Exception {
        client.completePendingCommand();
    }

    /**
     * @throws Exception
     */
    public void close() throws Exception {
        if (client.isConnected()) {
            client.disconnect();
        }
    }

    /**
     * @throws Exception
     */
    public void reconnect() throws Exception {
        if (!client.isConnected()) {
            // client = new FTPClient();
            client.connect(_host, _port);
            client.login(_username, _password);
            client.changeWorkingDirectory(_remotePath);

            // localPath = _localPath;
        }
    }

    /**
     * @throws Exception
     */
    public void forceReconnect() throws Exception {
        if (!client.isConnected()) {
            client.disconnect();
        }

        // client = new FTPClient();
        client.connect(_host, _port);
        client.login(_username, _password);
        client.changeWorkingDirectory(_remotePath);

        // localPath = _localPath;
    }

    /**
     * 获得输入流
     *
     * @param
     * @throws Exception
     */
    public OutputStream getOutputStream(String fileName) throws Exception {
        return client.storeFileStream(fileName);
    }

    /**
     * 将远程文件移动至远程历史目录
     *
     * @param fileName
     * @throws Exception
     */
    public void moveFileToRemoteHisDir(String fileName) throws Exception {
        if (client.listFiles(fileName).length == 0) {
            throw new Exception("在远程服务器上未找到文件" + fileName + ",文件移动至历史目录失败");
        }
        StringBuffer newFileName = new StringBuffer();
        newFileName.append(getRemotePathHis());
        newFileName.append(FILE_SPEARATROR);
        newFileName.append(fileName);
        rename(fileName, newFileName.toString());
    }

    /**
     * 获取远程文件历史目录
     *
     * @return
     * @throws com.ai.appframe2.common.Exception
     *
     */
    public String getRemotePathHis() throws Exception {
        if (remotePathHis == null || remotePathHis.length() < 1) {
            throw new Exception("未配置远程文件历史目录");
        }
        return remotePathHis;
    }

    public String getWorkingDirectory() throws Exception {
        if (FtpUtil.client != null) {
            return FtpUtil.client.printWorkingDirectory();
        }
        return null;
    }

    public void changeWorkingDirectory(String pathName) throws Exception {
        if (FtpUtil.client != null) {
            FtpUtil.client.changeWorkingDirectory(pathName);
        }
    }

    // public String getLocalPath() {
    // return this._localPath;
    // }
    //
    // public String getLocalPathTemp() {
    // return this._localPathTemp;
    // }

    public String getRemotePath() {
        return _remotePath;
    }

    /**
     * 向已有文件里面追加数据
     *
     * @param remoteName
     * @param in
     * @return
     * @throws Exception
     */
    public boolean appendFile(String remoteName, InputStream in) throws Exception {
        return client.appendFile(remoteName, in);
    }

    /**
     * 切换到指定目录(不存在就创建目录同时切换到新建的目录)
     *
     * @param directoryId
     * @throws Exception
     */
    public void changeToRightDir(String directoryId) throws Exception {
        if (client != null) {
            String ftpDir = client.printWorkingDirectory();
            if (ftpDir == null) {
                ftpDir = "/";
            }

            String curDir = null;

            if (directoryId.startsWith("/")) {
                curDir = directoryId;
            } else {
                if (!ftpDir.endsWith("/")) {
                    curDir = ftpDir + FILE_SPEARATROR + directoryId;
                } else {
                    curDir = ftpDir + directoryId;
                }
            }

            System.out.println("CHANGE DIR: " + curDir);
            boolean flag = client.changeWorkingDirectory(curDir);
            if (flag == false) {
                client.makeDirectory(directoryId);
                client.changeWorkingDirectory(curDir);
            }
        }
    }

    /** 本地字符编码 */
    private String LOCAL_CHARSET = "GBK";

    // FTP协议里面，规定文件名编码为iso-8859-1
    private String SERVER_CHARSET = "ISO-8859-1";

    public boolean uploadFile(String url, int port, String username, String password, String path, String filename,
        InputStream input) {
        boolean result = false;

        try {
            int reply;
            // 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftpClient.connect(url);
            // ftp.connect(url, port);// 连接FTP服务器
            // 登录
            ftpClient.login(username, password);
            ftpClient.setControlEncoding(encoding);
            // 检验是否连接成功
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                System.out.println("连接失败");
                ftpClient.disconnect();
                return result;
            }

            // 注意：有的FTP是需要先发送CLNT版本号的
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持，如果服务器支持就用UTF-8编码，否则就使用本地编码（GBK）.
                LOCAL_CHARSET = "UTF-8";
            }

            ftpClient.setControlEncoding(LOCAL_CHARSET);
            ftpClient.enterLocalPassiveMode();// 设置被动模式

            System.out.println("LOCAL_CHARSET:" + LOCAL_CHARSET);
            System.out.println("encoding:" + encoding);

            // 转移工作目录至指定目录下
            if (ftpClient.isAvailable()) {
                ftpClient.makeDirectory(path);
            }
            boolean change = ftpClient.changeWorkingDirectory(path);
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            if (change) {
                System.out.println("filename:" + filename);
                result = ftpClient.storeFile(new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET), input);
                if (result) {
                    System.out.println("上传成功!");
                }
            }
            input.close();
            ftpClient.logout();
        } catch (IOException e) {
            logger.error("", e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }

    /**
     * 根据文件名获得盘符
     *
     * @param fileName
     * @return
     */
    public static String getDisk(String fileName) {
        String[] temps = fileName.split(":");
        if (null != temps && temps.length > 0) {
            String disk = temps[0];
            return disk;
        }
        return "";
    }

    /**
     * @param ip
     * @param port
     * @param userName
     * @param userPwd
     * @param path
     * @throws SocketException
     * @throws IOException
     *             function:连接到服务器
     */
    public void connectServer(String ip, int port, String userName, String userPwd, String path) {
        ftpClient = new FTPClient();
        try {
            // 连接
            ftpClient.connect(ip, port);
            // 登录
            ftpClient.login(userName, userPwd);
            if (path != null && path.length() > 0) {
                // 跳转到指定目录
                ftpClient.changeWorkingDirectory(path);
            }
        } catch (SocketException e) {
            logger.error("", e);
        } catch (IOException e) {
            logger.error("", e);
        }
    }

    /**
     * @throws IOException
     *             function:关闭连接
     */
    public void closeServer() {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException e) {
                logger.error("", e);
            }
        }
    }

    /**
     * @param path
     * @return function:读取指定目录下的文件名
     * @throws IOException
     */
    public List<String> getFileList(String path) {
        List<String> fileLists = new ArrayList<String>();
        // 获得指定目录下所有文件名
        FTPFile[] ftpFiles = null;
        try {
            ftpFiles = ftpClient.listFiles(path);
        } catch (IOException e) {
            logger.error("", e);
        }
        for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
            FTPFile file = ftpFiles[i];
            if (file.isFile()) {
                fileLists.add(file.getName());
            }
        }
        return fileLists;
    }

    /**
     * @param fileName
     * @param sourceFile
     * @return
     * @throws IOException
     *             function:下载文件
     */
    public boolean unloadFile(String fileName, String sourceFile) {
        boolean flag = false;
        try {
            FileOutputStream fos = new FileOutputStream(fileName);
            flag = ftpClient.retrieveFile(sourceFile, fos);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            flag = false;
            logger.error("", e);
        }
        return flag;
    }

    /**
     * 返回一个文件流
     *
     * @param fileName
     * @return
     */
    public String readFile(String fileName) {
        String result = "";
        InputStream ins = null;
        try {
            ins = ftpClient.retrieveFileStream(fileName);

            // byte []b = new byte[ins.available()];
            // ins.read(b);
            BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
            String inLine = reader.readLine();
            while (inLine != null) {
                result += inLine + System.getProperty("line.separator");
                inLine = reader.readLine();
            }
            reader.close();
            if (ins != null) {
                ins.close();
            }

            // 主动调用一次getReply()把接下来的226消费掉. 这样做是可以解决这个返回null问题
            ftpClient.getReply();
        } catch (IOException e) {
            logger.error("", e);
        }
        return result;
    }

    /**
     * Description: 从FTP服务器下载文件
     *
     * @param url
     *            FTP服务器hostname
     * @param port
     *            FTP服务器端口
     * @param username
     *            FTP登录账号
     * @param password
     *            FTP登录密码
     * @param remotePath
     *            FTP服务器上的相对路径
     * @param fileName
     *            要下载的文件名
     * @param localPath
     *            下载后保存到本地的路径
     * @return
     */
    public boolean downFile(String url, int port, String username, String password, String remotePath, String fileName,
        String localPath) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(url, port);
            // 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    File localFile = new File(localPath + "/" + ff.getName());

                    OutputStream is = null;
					try {
						is = new FileOutputStream(localFile);
						ftp.retrieveFile(ff.getName(), is);
					} catch (Exception e) {
						logger.error("", e);
					} finally {
						if (is != null) {
							is.close();
						}
					}                    
                }
            }

            ftp.logout();
            success = true;
        } catch (IOException e) {
            logger.error("", e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    public boolean deleteFile(String url, int port, String username, String password, String remotePath,
        String fileName) throws Exception {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(url, port);
            // 如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftp.listFiles();

            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    ftp.deleteFile(fileName);
                }

            }

            ftp.logout();
            success = true;
        } catch (IOException e) {
            logger.error("", e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    logger.error("", ioe);
                }
            }
        }
        return success;
    }
}
